package com.sz.biz.trade.ord.service.impl;

import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.sz.biz.trade.ord.dto.*;
import com.sz.biz.trade.ord.entity.TrdOrder;
import com.sz.biz.trade.ord.entity.TrdOrderDelivery;
import com.sz.biz.trade.ord.entity.TrdOrderStatus;
import com.sz.biz.common.AbstractVersionEntityService;
import com.sz.biz.trade.ord.service.TrdOrderDeliveryService;
import com.sz.biz.trade.ord.service.TrdOrderGoodsRelService;
import com.sz.biz.trade.ord.service.TrdOrderService;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.FreeMarkerTemplateUtils;
import com.sz.common.core.system.utils.PDFUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.base.utils.UUIDGenerator;
import com.sz.biz.logistics.constants.ErrorCodes;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.entity.SysFile;
import com.sz.common.core.system.service.SysFileService;
import com.lowagie.text.DocumentException;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Function: 贸易订单服务<br>
 * Author: jifeixing <br>
 * Date: 2017-07-15 14:10:00
 */
@Service("trdOrderDeliveryService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class TrdOrderDeliveryServiceImpl extends AbstractVersionEntityService implements TrdOrderDeliveryService {

    @Autowired
    private TrdOrderGoodsRelService trdOrderGoodsRelService;

    @Autowired
    private TrdOrderService trdOrderService;

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private SysFileService sysFileService;

    @Override
    protected String getMapperNamespace() {
        return "TrdOrderDeliveryMapper";
    }

    /**
     * 收货确认单
     * @param orderDeliverySaveDto
     */
    @Override
    public void save(TrdOrderDeliverySaveDto orderDeliverySaveDto) {
        if(null == orderDeliverySaveDto){
            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_ILLEGAL);
        }
        TrdOrder order = trdOrderService.findFullInfoByOrderNo(orderDeliverySaveDto.getOrderNo());
        if (!trdOrderService.isNeedBuildPDF(order)) {
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "非SUNRUN订单，不支持该方法");
        }
        TrdOrderDelivery trdOrderDelivery = new TrdOrderDelivery();
        BeanUtils.copyProperties(orderDeliverySaveDto, trdOrderDelivery);
        trdOrderDelivery.setDeliveryNo(generateNewUid());
        trdOrderDelivery.setCreateUserId(PrincipalUtils.getAccountId());
        trdOrderDelivery.setLastUpdateUserId(PrincipalUtils.getAccountId());
        dao.save(getSqlName("insertSelective"), trdOrderDelivery);
        //修改订单下已有商品为删除状态
        trdOrderGoodsRelService.updateToDelete(orderDeliverySaveDto.getOrderNo(), 1);
        //回写增值数及不含增值税金额
        BigDecimal vat = orderDeliverySaveDto.getVat();
        BigDecimal noVat = orderDeliverySaveDto.getNoVat();
        //计算订单金额
        BigDecimal amountDue = trdOrderService.saveOrderGoods(orderDeliverySaveDto.getOrderGoods(), orderDeliverySaveDto.getOrderNo(), true, 1, vat);
        //更新订单状态为已签收状态
        TrdOrder trdOrder = new TrdOrder();
        trdOrder.setOrderNo(orderDeliverySaveDto.getOrderNo());
        trdOrder.setOrderStatus(TrdOrderStatus.SIGNED);
        trdOrder.setAmountDue(amountDue);
        trdOrder.setOrderGoods(orderDeliverySaveDto.getOrderGoods());
        //获取系统当前时间
        Date now = dao.getDbDate();
        trdOrder.setReceiptTime(now);
        //回写增值数及不含增值税金额
        trdOrder.setVat(vat);
        trdOrder.setNoVat(noVat);
        trdOrderService.updateOrder(trdOrder);
    }

    /**
     * 非SUNRUN订单收货确认单
     * @param normalTrdOrderDeliverySaveDto
     */
    @Override
    public void saveNormal(NormalTrdOrderDeliverySaveDto normalTrdOrderDeliverySaveDto) {
        if(null== normalTrdOrderDeliverySaveDto){
            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_ILLEGAL);
        }
        if(null== normalTrdOrderDeliverySaveDto.getOrderNo()){
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON,"订单号不能为空");
        }
        TrdOrder order = trdOrderService.findFullInfoByOrderNo(normalTrdOrderDeliverySaveDto.getOrderNo());
        if(trdOrderService.isNeedBuildPDF(order)){
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "非SUNRUN订单，不支持该方法");
        }
        //修改订单下已有商品为删除状态
        trdOrderGoodsRelService.updateToDelete(normalTrdOrderDeliverySaveDto.getOrderNo(), 1);
        //回写增值数及不含增值税金额
        BigDecimal vat = normalTrdOrderDeliverySaveDto.getVat();
        BigDecimal noVat = normalTrdOrderDeliverySaveDto.getNoVat();
        //计算订单金额
        BigDecimal amountDue = trdOrderService.saveOrderGoods(normalTrdOrderDeliverySaveDto.getOrderGoods(), normalTrdOrderDeliverySaveDto.getOrderNo(), true, 1, vat);
        //更新订单状态为已签收状态
        TrdOrder trdOrder = new TrdOrder();
        trdOrder.setOrderNo(normalTrdOrderDeliverySaveDto.getOrderNo());
        trdOrder.setOrderStatus(TrdOrderStatus.SIGNED);
        trdOrder.setAmountDue(amountDue);
        trdOrder.setOrderGoods(normalTrdOrderDeliverySaveDto.getOrderGoods());
        //获取系统当前时间
        Date now = dao.getDbDate();
        trdOrder.setReceiptTime(now);
        //回写增值数及不含增值税金额
        trdOrder.setVat(vat);
        trdOrder.setNoVat(noVat);
        trdOrderService.updateOrder(trdOrder);
    }

    /**
     * 根据的订单号获取收货确认单信息
     * @param orderNo
     * @return
     */
    @Override
    public TrdOrderDeliveryInfoDto findByOrderNo(String orderNo) {
        TrdOrderDeliveryInfoDto trdOrderDeliveryInfoDto = (TrdOrderDeliveryInfoDto) dao.findForObject(getSqlName("findByOrderNo"), orderNo);
        if(null != trdOrderDeliveryInfoDto){
            if(!StringUtils.isEmpty(trdOrderDeliveryInfoDto.getOrderStatus())){
                TrdOrderStatus trdOrderStatus = TrdOrderStatus.valueOfEnum(trdOrderDeliveryInfoDto.getOrderStatus());
                trdOrderDeliveryInfoDto.setOrderStatusName(trdOrderStatus.getName());
            }
            List<TrdOrderGoodsRelDto> trdOrderGoodsRels = trdOrderGoodsRelService.findByOrderNo(orderNo, 2);
            if(trdOrderGoodsRels!=null){
            	for(TrdOrderGoodsRelDto trdOrderGoodsRelDto:trdOrderGoodsRels){
                	trdOrderGoodsRelDto.setGoodsTotal(trdOrderGoodsRelDto.getGoodsPrice().multiply( trdOrderGoodsRelDto.getGoodsNum() ));
                }
            }  
            trdOrderDeliveryInfoDto.setOrderGoodsDelivery(trdOrderGoodsRels);
        }
        return trdOrderDeliveryInfoDto;
    }
    /**
     * 根据订单号获取收货确认单信息后生成PDF文件
     * @param orderNo
     * @return
     */
    @Override
    public SysFile exportPDF(String orderNo){
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MMMM-yyyy", Locale.US);
        TrdOrderDeliveryInfoDto trdOrderDeliveryInfoDto = trdOrderService.getDeliveryByOrder(orderNo);
        if (trdOrderDeliveryInfoDto != null) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("custCompanyName", trdOrderDeliveryInfoDto.getCustCompanyName());
            dataMap.put("custCompanyAddress", trdOrderDeliveryInfoDto.getCustCompanyAddress());
            dataMap.put("dealer", trdOrderDeliveryInfoDto.getDealer());
            dataMap.put("orderNo", trdOrderDeliveryInfoDto.getOrderNo());
            dataMap.put("deliveryNo", trdOrderDeliveryInfoDto.getDeliveryNo());
            dataMap.put("dealTime",trdOrderDeliveryInfoDto.getDealTime()!=null? sdf.format(trdOrderDeliveryInfoDto.getDealTime()):"");
            dataMap.put("shipName", trdOrderDeliveryInfoDto.getShipName());
            dataMap.put("destinationPort", trdOrderDeliveryInfoDto.getDestinationPort());
            dataMap.put("bank", trdOrderDeliveryInfoDto.getBank());
            dataMap.put("bankAddress", trdOrderDeliveryInfoDto.getBankAddress());
            dataMap.put("swiftCode", trdOrderDeliveryInfoDto.getSwiftCode());
            dataMap.put("paymentTime",trdOrderDeliveryInfoDto.getPaymentTime()!=null?sdf.format(trdOrderDeliveryInfoDto.getPaymentTime()):"");
            dataMap.put("account", trdOrderDeliveryInfoDto.getAccount());
            dataMap.put("goodsTotalVat",trdOrderDeliveryInfoDto.getGoodsTotalVat());
            dataMap.put("accountHolder", trdOrderDeliveryInfoDto.getAccountHolder());
            dataMap.put("currencyCode", trdOrderDeliveryInfoDto.getCurrencyCode());
            dataMap.put("receiptTime",trdOrderDeliveryInfoDto.getReceiptTime()!=null? sdf.format(trdOrderDeliveryInfoDto.getReceiptTime()):"");
            dataMap.put("noVat",trdOrderDeliveryInfoDto.getNoVat());
            dataMap.put("vat",trdOrderDeliveryInfoDto.getVat());
            dataMap.put("companyName", trdOrderDeliveryInfoDto.getCompanyName());
            dataMap.put("companyAddress", trdOrderDeliveryInfoDto.getCompanyAddress());
            dataMap.put("companyPhone", trdOrderDeliveryInfoDto.getCompanyPhone());
            dataMap.put("companyFax", trdOrderDeliveryInfoDto.getCompanyFax());
            dataMap.put("companyEmail", trdOrderDeliveryInfoDto.getCompanyEmail());
            if (trdOrderDeliveryInfoDto.getOrderGoodsDelivery() != null && trdOrderDeliveryInfoDto
                    .getOrderGoodsDelivery().size() > 0) {
                dataMap.put("goodList", trdOrderDeliveryInfoDto.getOrderGoodsDelivery());
            }
            String content = FreeMarkerTemplateUtils.freeMarkerRender(dataMap, "receiptConfirmation.ftl");
            content = FreeMarkerTemplateUtils.tidyHtml(content);
            ByteArrayOutputStream outputStream = null;
            try {
                outputStream = (ByteArrayOutputStream) PDFUtils.getPdfStream(content);
            } catch (IOException e) {
                e.printStackTrace();
                logger.error(e.getMessage());
            } catch (DocumentException e) {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            if (outputStream != null) {
                ByteArrayInputStream swapStream = new ByteArrayInputStream(outputStream.toByteArray());
                long size = outputStream.toByteArray().length;
                StorePath storePath = storageClient.uploadFile(swapStream, size,
                        "pdf", null);
                SysFile sysFile = sysFileService.uploadFile(0, null, UUIDGenerator.generateOrderedUUID() +
                        "OrderDeliveryInfo", "application/pdf", "OrderDeliveryInfoPDF", storePath.getFullPath(), size);
                return  sysFile;
            }
        }
        return null;
    }
    /**
     * 订单确认单PDF导出路径
     * @param orderNo
     * @return
     */
    @Override
    public PathPDFDto findPathByOrderNo(String orderNo) {
        PathPDFDto pathPDFDto = (PathPDFDto) dao.findForObject(getSqlName("findPathByOrderNo"), orderNo);
        if (pathPDFDto != null) {
            SysFile sysFile = sysFileService.getFileInfo(pathPDFDto.getFileId());
            if (sysFile != null) {
                pathPDFDto.setPath(sysFile.getFileLocation());
            }
        }
        return pathPDFDto;
    }
}